#ifndef SKYROAD_FLAGS_H_
#define SKYROAD_FLAGS_H_

template<typename self_type, typename type> 
struct flag_with_self_type
{
    flag_with_self_type(self_type * self, const type& val = type() ) : m_val(val), m_self(self) 
    {

    }

    flag_with_self_type(const flag_with_self_type & other) : m_val(other.m_val)
    {

    }

    const type & operator()() const
    {
        return m_val;
    }
    self_type & operator()(const type & val)
    {
        m_val = val; 
        return *m_self;
    }

    void operator=(const self_type & other) 
    {
        m_val = other.m_val;
    }

private:
    type m_val;
    self_type * m_self;
};

    /** 
        @brief Can hold a flag. See dealing_with_flags
    */
template<typename self_type>
struct flag
{
    template<typename val_type>
    struct t : flag_with_self_type<self_type,val_type>
    {
        typedef flag_with_self_type<self_type,val_type> flag_base_type;
        t(self_type * self, const val_type& val = val_type() ) : flag_base_type(self,val) 
        {

        }
    };
};

#endif